#define _CRT_SECURE_NO_WARNINGS 1;
#include <stdio.h>
// printf()，库函数，需要引用stdio.h这个头文件
#include <string.h>
// 数据类型：
// char,short,int,long,long long,float,double

// 作用域：
// 局部变量的作用域：变量所在的局部范围
// 全局变量的作用域：整个工程

// 声明外部变量，在 ext_test.c 文件中
extern int g_val;
// 声明函数
extern int mult(int, int);

// 生命周期：
// 变量：变量的创建和销毁之间的时间段
// 局部变量：进入作用域生命周期开始，离开作用域结束
// 全局：整个程序的生命周期

// 常量：
// 1.字面常量
// 2.const修饰的常变量
// const int num = 10 ; // num是常变量，具有常属性（不能被改变的属性）
// int arr[num] = {0}; // num是变量，报错！
// 3.#define定义的标识符常量
#define MAX 100
// 4.枚举常量：可一一列举
enum sex {
	MALE,
	FEMALE,
	SECRET
};
typedef unsigned int u_int; // 起别名
int main() {
	int a = 0;
	float b = 1;
	int arr[MAX] = { 1 };
	// 字符串就是一串字符，双引号括起来的
	char str[] = "Hello";
	char str1[] = { 'H','e','l','l','o' };
	//scanf("%d %f",&a,&b);
	//printf("hello world\n%d,%f\n",a,b);
	printf("%d\n", g_val);
	//printf("%d\n",arr[0]);
	//printf("%d\n", strlen(str));
	//printf("%d\n",strlen(str1));
	printf("(are you OK??)\n"); // 并不支持三字母词
	 //转义字符
	printf("%c\n", '\'');
	printf("%s\n", "\"");
	printf("c:\\test\\test.c\n");
	for (int i = 0; i < 5; i++) {
		//printf("%s\n \a", "xm_0025");
	}
	printf("%c\n", '\130'); // \ddd 八进制数，对应88（十进制）
	// ASCII值为88的是X
	printf("%d\n", '\x30'); // 48
	printf("%d\n", strlen("abc")); // 3
	printf("%d\n", strlen("c:\test\328\test.c")); // 14

	// printf 打印数据时，可指定打印的格式
	//if_init();
	//printf("%d + %d = %d\n", 5, 10, sum(5, 10));
	// 数组：
	//_arr();
	operator();
	return 0;
}

// if选择
void if_init() {
	int selected = 0;
	printf("选择？(0/1)\n");
	int input = scanf("%d", &selected);
	if (selected == 1) {
		printf("好的");
	}
	else {
		printf("不太好！");
	}
}

// 求两数之和
int sum(int a, int b) {
	return a + b;
}

// 数组
_arr() {
	int a[] = { 1,2,3,4,5,6,7,8,9,10 };
	char str[5] = { 'a','b','c' };
	for (int i = 0; i < 10; i++) {
		printf("数组打印：%d\n", a[i]);
	}
	printf("str = %s", str);

}

// 操作符
operator() {
	int d = 0;
	int arr[10] = { 0 }; // 10 * 4 byte
	int a = 2;
	int b = a << 1; // 左移操作：移动的是二进制位
	// sizeof 是一个操作符而非函数（函数的括号是不可以省略的）
	// 计算类型或变量的大小
	printf("int_size = %d\n", sizeof(int));
	printf("a_size = %d\n", sizeof a); // 可以省略括号
	printf("arr_totalSize = %d\n", sizeof arr);
	printf("arr_size = %d\n", sizeof arr / sizeof arr[0]); // 数组长度
	printf("b = %d\n", b);
	// 取反操作：整数在内存中是以补码形式存储的，打印出来的是整数的原码形式
	// 0……0000 取反 1……1111（补）→1……0001（原）
	printf("~d = %d\n", ~d); // -1

	// ++、--
	int e = 10;
	int f = e++; // 先赋值再自增
	int h = 1;
	int i = (++h) + (++h) + (++h);
	printf("e = %d\n", e); // 11
	printf("f = %d\n", f); // 10
	printf("i = %d\n", i); // 12

	// 三目操作符
	printf("res => %s\n", -1 ? "true" : "false");
	// 逗号表达式
	printf("res = %d\n", (2, 4 + 5, 6));
	// 函数后面的括号就是函数调用操作符

	/*
	* 关键字：
	* auto：局部变量都是用auto修饰的，即自动创建和销毁；
	* extern：可用来声明外部符号；
	* register：建议将某变量存放到寄存器中，具体能不能存要看编译器；
	* 数据可存位置：【内存、硬盘、网盘、高速cache、寄存器……】
	*
	* 注意：define、include不是关键字，而是预处理指令；
	*/

	// typedefine：类型重定义
	u_int num = 100;
	printf("typedf => num = %d\n", num);
	/*
	* static：
	* 修饰局部变量：
		改变了局部变量的生命周期（本质改变的是变量的存储类型）
		内存一般划分为：栈区（局部变量、函数参数）；
		堆区（动态内存分配）；
		静态区（全局变量、static修饰的静态变量）；
	* 修饰全局：
	*	使得这个全局变量只能在自己所在的源文件（.c）内部使用，其他源文件无法使用；
	*	全局变量可在其他源文件内部使用，因为其具有外部链接属性；
	*	而使用static修饰后，则变成了内部链接属性，其他原文件就不能链接到 此全局变量了；
	* 修饰函数：【和static修饰全局变量同理，同上】
	*/
	for (int i = 0; i < 10; i++) {
		test_static();
	}
	printf("extern Mult -> %d", mult(10, 9));

}

// static 的用法
test_static() {
	static int a = 1; // 2~11
	//int a = 1; // 10个2
	a++;
	printf("test : %d\n", a);
}